/*
    这里实现了自动的路由模块与路由守卫安装
    路由模块: ./routes/*.route.ts, 需要 export default RouteRecordRaw | RouteRecordRaw[]
    路由守卫: ./guards/*.guard.ts, 需要 export default GuardInstaller
 */

import { createRouter, createWebHashHistory, Router, RouteRecordRaw } from "vue-router";

/**
 * 路由守卫安装器, 每个guard的默认导出都需要是这个类型的
 */
export interface GuardInstaller {
    /**
     * 优先级, 值越小优先级越高
     */
    priority: number
    /**
     * 安装函数
     * @param router 路由对象
     */
    install: (router: Router) => void
}

// 导入routes目录下的所有模块
const routeModules = import.meta.glob("./routes/*.route.ts", { eager: true });
// 导入guards目录下的所有模块
const guardModules = import.meta.glob("./guards/*.guard.ts", { eager: true });

/**
 * 获取Record中所有的导出, 这个Record是import.meta.glob返回的Module对象, 每个Module对象都有个默认导出
 * @param record 模块
 * @param predicate 附加筛选器
 */
function extractExport<E>(record: Record<string, any>, predicate: ((name: string, value: E) => boolean) = () => true): E[] {
    return Reflect.ownKeys(record)
        .map(name => {
            if (typeof name === "string") {
                const value = record[name] as any;
                if (value && value[Symbol.toStringTag] === "Module" && value.default) {
                    return { name: name, export: value.default };
                }
                throw new Error(`File [${name}] is not a compliant module`);
            }
            return null;
        })
        .filter(v => !!v && predicate(v!.name, v!.export))
        .map(v => v!.export) as E[];
}

const router = createRouter({
    history: createWebHashHistory(),
    routes: extractExport(routeModules).flatMap(v => v) as RouteRecordRaw[]
});


// 提取出所有的路由守卫模块(export default)并执行安装
extractExport<GuardInstaller>(guardModules).sort((a, b) => a.priority - b.priority).forEach(value => {
    value.install(router);
});


export default router;